home *** CD-ROM | disk | FTP | other *** search
/ Reverse Code Engineering RCE CD +sandman 2000 / ReverseCodeEngineeringRceCdsandman2000.iso / RCE / Library / Manuels & Misc / Assembly / AOA.ZIP / CH13 / COPYUC.ASM < prev    next >
Encoding:
Assembly Source File  |  1996-02-24  |  6.6 KB  |  298 lines

  1.         include        stdlib.a
  2.         includelib    stdlib.lib
  3.  
  4. cseg        segment        byte public 'CODE'
  5.         assume        cs:cseg, ds:nothing, es:dseg, ss:sseg
  6.  
  7. ; Note: The constants CR (0dh) and LF (0ah) appear within the
  8. ; stdlib.a include file.
  9.  
  10. tab        equ    09h
  11.  
  12. MainPgm     proc    far
  13.  
  14. ; Properly set up the segment registers:
  15.  
  16.         mov    ax, seg dseg
  17.         mov    es, ax            ;Leave DS pointing at PSP
  18.  
  19. ;---------------------------------------------------------------
  20.  
  21. ; First, parse the command line to get the filename:
  22.  
  23.         mov    es:GotName1, 0        ;Init flags that tell us if
  24.         mov    es:GotName2, 0        ; we╒ve parsed the filenames 
  25.         mov    es:ConvertLC,0        ; and the ╥/U" switch.
  26.  
  27. ; Okay, begin scanning and parsing the command line
  28.  
  29.         mov    si, 81h             ;Pointer to command line
  30. SkipDelimiters:    
  31.         lodsb                ;Get next character
  32.         call    TestDelimiter
  33.         je    SkipDelimiters
  34.  
  35. ; Determine if this is a filename or the /U switch
  36.  
  37.         cmp    al, '/'
  38.         jnz    MustBeFN
  39.  
  40. ; See if it's "/U" here-
  41.  
  42.         lodsb
  43.         and    al, 5fh             ;Convert "u" to "U"
  44.         cmp    al, 'U'
  45.         jnz    NotGoodSwitch
  46.         lodsb                ;Make sure next char is
  47.         cmp    al, cr            ; a delimiter of some sort
  48.         jz    GoodSwitch
  49.         call    TestDelimiter
  50.         jne    NotGoodSwitch
  51.  
  52. ; Okay, it's "/U" here.
  53.  
  54. GoodSwitch:    mov    es:ConvertLC, 1        ;Convert LC to UC
  55.         dec    si            ;Back up in case it's CR
  56.         jmp    SkipDelimiters        ;Move on to next item.
  57.  
  58. ; If a bad switch was found on the command line, print an error 
  59. ; message and abort-
  60.  
  61. NotGoodSwitch:
  62.         print
  63.         byte    cr,lf
  64.         byte    'Illegal switch, only "/U" is allowed!',cr,lf
  65.         byte    'Aborting program execution.',cr,lf,0
  66.         jmp    PgmExit
  67.  
  68. ; If it's not a switch, assume that it's a valid filename and 
  69. ; handle it down here-
  70.  
  71. MustBeFN:    cmp    al, cr            ;See if at end of cmd line
  72.         je    EndOfCmdLn
  73.  
  74. ; See if it's filename one, two, or if too many filenames have been
  75. ; specified-
  76.  
  77.         cmp    es:GotName1, 0
  78.         jz    Is1stName
  79.         cmp    es:GotName2, 0
  80.         jz    Is2ndName
  81.  
  82. ; More than two filenames have been entered, print an error message
  83. ; and abort.
  84.  
  85.         print
  86.         byte    cr,lf
  87.         byte    'Too many filenames specified.',cr,lf
  88.         byte    'Program aborting...',cr,lf,lf,0
  89.         jmp    PgmExit
  90.  
  91. ; Jump down here if this is the first filename to be processed-
  92.  
  93. Is1stName:    lea    di, FileName1
  94.         mov    es:GotName1, 1
  95.         jmp    ProcessName
  96.  
  97. Is2ndName:    lea    di, FileName2
  98.         mov    es:GotName2, 1
  99. ProcessName:
  100.         stosb                ;Store away character in name
  101.         lodsb                ;Get next char from cmd line
  102.         cmp    al, cr
  103.         je    NameIsDone
  104.         call    TestDelimiter
  105.         jne    ProcessName
  106.  
  107. NameIsDone:    mov    al, 0            ;Zero terminate filename
  108.         stosb
  109.         dec    si            ;Point back at previous char
  110.         jmp    SkipDelimiters        ;Try again.
  111.  
  112. ; When the end of the command line is reached, come down here and 
  113. ; see if both filenames were specified.
  114.  
  115.         assume        ds:dseg
  116.  
  117. EndOfCmdLn:    mov    ax, es            ;Point DS at DSEG
  118.         mov    ds, ax
  119.  
  120. ; We're at the end of the filename, so zero-terminate it as
  121. ;  required by DOS.
  122.  
  123. GotName:    mov    ax, es            ;Point DS at DSEG
  124.         mov    ds, ax
  125.  
  126. ; See if the names were supplied on the command line.
  127. ; If not, prompt the user and read them from the keyboard
  128.  
  129.         cmp    GotName1, 0        ;Was filename #1 supplied?
  130.         jnz    HasName1
  131.         mov    al, '1'            ;Filename #1
  132.         lea    si, Filename1
  133.         call    GetName         ;Get filename #1
  134.  
  135. HasName1:    cmp    GotName2, 0        ;Was filename #2 supplied?
  136.         jnz    HasName2
  137.         mov    al, '2'         ;If not, read it from kbd.
  138.         lea    si, FileName2
  139.         call    GetName
  140.  
  141. ; Okay, we've got the filenames, now open the files and copy the 
  142. ; source file to the destination file.
  143.  
  144. HasName2:       mov     ah, 3dh
  145.         mov    al, 0            ;Open file for reading
  146.         lea    dx, Filename1        ;File to open
  147.         int    21h
  148.         jnc    GoodOpen1
  149.  
  150.         print
  151.         byte    'Cannot open file, aborting program...',cr,lf,0
  152.         jmp    PgmExit
  153.  
  154. ; If the source file was opened successfully, save the file handle.
  155.  
  156. GoodOpen1:    mov    FileHandle1, ax        ;Save file handle
  157.  
  158. ; Open (CREATE, actually) the second file here.
  159.  
  160.         mov    ah, 3ch             ;Create file
  161.         mov    cx, 0            ;Standard attributes
  162.         lea    dx, Filename2        ;File to open
  163.         int    21h
  164.         jnc    GoodCreate
  165.  
  166. ; Note: the following error code relies on the fact that DOS 
  167. ; automatically closes any open source files when the program
  168. ; terminates.
  169.  
  170.         print
  171.         byte    cr,lf
  172.         byte    'Cannot create new file, aborting operation'
  173.         byte    cr,lf,lf,0
  174.         jmp    PgmExit
  175.  
  176. GoodCreate:    mov    FileHandle2, ax        ;Save file handle
  177.  
  178. ; Now process the files
  179.  
  180. CopyLoop:    mov    ah, 3Fh            ;DOS read opcode
  181.         mov    bx, FileHandle1        ;Read from file #1
  182.         mov    cx, 512         ;Read 512 bytes
  183.         lea    dx, buffer        ;Buffer for storage
  184.         int    21h
  185.         jc    BadRead
  186.         mov    bp, ax            ;Save # of bytes read
  187.  
  188.         cmp    ConvertLC,0        ;Conversion option active?
  189.         jz    NoConversion
  190.  
  191. ; Convert all LC in buffer to UC-
  192.  
  193.         mov    cx, 512
  194.         lea    si, Buffer
  195.         mov    di, si
  196. ConvertLC2UC:
  197.         lodsb
  198.         cmp    al, 'a'
  199.         jb    NoConv
  200.         cmp    al, 'z'
  201.         ja    NoConv
  202.         and    al, 5fh
  203. NoConv:     stosb
  204.         loop    ConvertLC2UC
  205.  
  206. NoConversion:
  207.         mov    ah, 40h            ;DOS write opcode
  208.         mov    bx, FileHandle2        ;Write to file #2
  209.         mov    cx, bp            ;Write however many bytes
  210.         lea    dx, buffer        ;Buffer for storage
  211.         int    21h
  212.         jc    BadWrite
  213.         cmp    ax, bp            ;Did we write all of the 
  214.         jnz    jDiskFull        ; bytes?
  215.         cmp    bp, 512            ;Were there 512 bytes read?
  216.         jz    CopyLoop
  217.         jmp    AtEOF
  218. jDiskFull:    jmp    DiskFull
  219.  
  220. ; Various error messages:
  221.  
  222. BadRead:    print
  223.         byte    cr,lf
  224.         byte    'Error while reading source file, aborting '
  225.         byte    'operation.',cr,lf,0
  226.         jmp    AtEOF
  227.  
  228. BadWrite:        print
  229.         byte    cr,lf
  230.                 byte    'Error while writing destination file, aborting'
  231.         byte    ' operation.',cr,lf,0
  232.         jmp    AtEOF
  233.  
  234. DiskFull:        print
  235.         byte    cr,lf
  236.         byte    'Error, disk full.  Aborting operation.',cr,lf,0
  237.  
  238. AtEOF:        mov    bx, FileHandle1        ;Close the first file
  239.         mov    ah, 3Eh
  240.         int    21h
  241.         mov    bx, FileHandle2        ;Close the second file
  242.         mov    ah, 3Eh
  243.         int    21h
  244.  
  245. PgmExit:    ExitPgm
  246. MainPgm     endp
  247.  
  248. TestDelimiter        proc    near
  249.         cmp    al, ' '
  250.         je    xit
  251.         cmp    al, ','
  252.         je    xit
  253.         cmp    al, Tab
  254.         je    xit
  255.         cmp    al, ';'
  256.         je    xit
  257.         cmp    al, '='
  258. xit:        ret
  259. TestDelimiter        endp
  260.  
  261. ; GetName- Reads a filename from the keyboard.  On entry, AL 
  262. ; contains the filename number and DI points at the buffer in ES 
  263. ; where the zero-terminated filename must be stored.
  264.  
  265. GetName        proc    near
  266.         print
  267.         byte    'Enter filename #',0
  268.         putc
  269.         mov    al, ':'
  270.         putc
  271.         gets
  272.         ret
  273. GetName        endp
  274. cseg        ends
  275.  
  276. dseg        segment    byte public 'data'
  277.  
  278. PSP        word    ?
  279. Filename1    byte    128 dup (?)    ;Source filename
  280. Filename2    byte    128 dup (?)    ;Destination filename
  281. FileHandle1    word    ?
  282. FileHandle2    word    ?
  283. GotName1    byte    ?
  284. GotName2    byte    ?
  285. ConvertLC    byte    ?
  286. Buffer        byte    512 dup (?)
  287.  
  288. dseg        ends
  289.  
  290. sseg        segment        byte stack 'stack'
  291. stk        word    0ffh dup (?)
  292. sseg        ends
  293.  
  294. zzzzzzseg    segment        para public 'zzzzzz'
  295. LastBytes    byte        16 dup (?)
  296. zzzzzzseg    ends
  297.         end    MainPgm
  298.